package demo; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebListener; import javax.servlet.annotation.WebServlet; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.boot.context.embedded.FilterRegistrationBean; import org.springframework.boot.context.embedded.ServletListenerRegistrationBean; import org.springframework.boot.context.embedded.ServletRegistrationBean; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; class JeeComponentsBeanFactoryPostProcessor implements BeanFactoryPostProcessor { private static final String WEB_SERVLET_ANNOTATION_TYPE = "javax.servlet.annotation.WebServlet"; private static final String WEB_FILTER_ANNOTATION_TYPE = "javax.servlet.annotation.WebFilter"; private static final String WEB_LISTENER_ANNOTATION_TYPE = "javax.servlet.annotation.WebListener"; private static final Set<String> SUPPORTED_WEB_ANNOTATION_TYPES = new LinkedHashSet<>(Arrays.asList( WEB_SERVLET_ANNOTATION_TYPE, WEB_FILTER_ANNOTATION_TYPE, WEB_LISTENER_ANNOTATION_TYPE)); private final String basePackage; public JeeComponentsBeanFactoryPostProcessor(String basePackage) { this.basePackage = basePackage; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); configureIncludeFilters(provider, cl); Set<BeanDefinition> candiates = provider.findCandidateComponents(basePackage); registerJeeComponents(beanFactory, cl, candiates); } @SuppressWarnings("unchecked") private void configureIncludeFilters(ClassPathScanningCandidateComponentProvider provider, ClassLoader cl) { for (String annotationType : SUPPORTED_WEB_ANNOTATION_TYPES) { try { AnnotationTypeFilter filter = new AnnotationTypeFilter((Class<? extends Annotation>) ClassUtils.forName( annotationType, cl)); provider.addIncludeFilter(filter); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } private void registerJeeComponents(ConfigurableListableBeanFactory beanFactory, ClassLoader cl, Set<BeanDefinition> candiates) { for (BeanDefinition bd : candiates) { try { Class<?> beanClass = ClassUtils.forName(bd.getBeanClassName(), cl); WebServlet webServlet = beanClass.getDeclaredAnnotation(WebServlet.class); WebFilter webFilter = beanClass.getDeclaredAnnotation(WebFilter.class); WebListener webListener = beanClass.getDeclaredAnnotation(WebListener.class); DefaultListableBeanFactory targetBeanFactory = (DefaultListableBeanFactory) beanFactory; if (webServlet != null) { createAndRegisterServletBean(targetBeanFactory, bd, beanClass, webServlet); } else if (webFilter != null) { createAndRegisterServletFilterBean(targetBeanFactory, bd, beanClass, webFilter); } else if (webListener != null) { createAndRegisterWebListenerBean(targetBeanFactory, bd, beanClass, webListener); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } private void createAndRegisterWebListenerBean(DefaultListableBeanFactory beanFactory, BeanDefinition bd, Class<?> beanClass, WebListener webListener) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ServletListenerRegistrationBean.class); builder.addPropertyValue("listener", bd); String beanName = StringUtils.uncapitalize(beanClass.getSimpleName()); beanFactory.registerBeanDefinition(beanName, builder.getBeanDefinition()); } private void createAndRegisterServletFilterBean(DefaultListableBeanFactory beanFactory, BeanDefinition bd, Class<?> beanClass, WebFilter webFilter) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(FilterRegistrationBean.class); builder.addPropertyValue("filter", bd); builder.addPropertyValue("urlPatterns", new LinkedHashSet<>(Arrays.asList(webFilter.urlPatterns()))); String beanName = webFilter.filterName().isEmpty() ? StringUtils.uncapitalize(beanClass.getSimpleName()) : webFilter.filterName(); beanFactory.registerBeanDefinition(beanName, builder.getBeanDefinition()); } private void createAndRegisterServletBean(DefaultListableBeanFactory defaultListeableBeanFactory, BeanDefinition bd, Class<?> beanClass, WebServlet webServlet) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ServletRegistrationBean.class); builder.addPropertyValue("servlet", bd); builder.addPropertyValue("urlMappings", new LinkedHashSet<>(Arrays.asList(webServlet.urlPatterns()))); String beanName = webServlet.name().isEmpty() ? StringUtils.uncapitalize(beanClass.getSimpleName()) : webServlet .name(); defaultListeableBeanFactory.registerBeanDefinition(beanName, builder.getBeanDefinition()); } }